package com.conversationboard.api;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.SecurityContext;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import com.conversationboard.api.xml.ApiXPath;
import com.conversationboard.api.xml.XmlUtils;
import com.conversationboard.authenticator.Obfuscator;

public class LoginProcessor implements Processor {

	/* Input Form: <Login><LoginId>loginID</LoginId><Password>password</Password>
	 * <Encrypted>Yes|No</Encrypted><ReturnEncryptedPassword>Yes|No</ReturnEncryptedPassword></Login> */

	public String processXml(String requestXml, SecurityContext securityContext, HttpServletRequest request) throws ApiException {

		String loginId = "";
		String password = "";
		String returnEncryptedPassword = "";

		try {

			Document document = XmlUtils.getDocument(requestXml);

			loginId = (String) ApiXPath.loginExpression.evaluate(document, XPathConstants.STRING);
			password = (String) ApiXPath.passwordExpression.evaluate(document, XPathConstants.STRING);
			returnEncryptedPassword = (String) ApiXPath.returnEncryptedPasswordExpression.evaluate(document, XPathConstants.STRING);

			if (securityContext.getUserPrincipal() == null) {

				String encrypted = (String) ApiXPath.encryptedExpression.evaluate(document, XPathConstants.STRING);

				/* If the password is encrypted, then decrypt it before trying to log in */

				if (encrypted.equalsIgnoreCase("YES")) {
					password = Obfuscator.decrypt(password);
				}

				/* Try to log in if you're not already logged in */

				request.login(loginId, password);

				/* If the userPrincipal is still null, then we failed to log in */
				if (securityContext.getUserPrincipal() == null) {
					return "<Login><Status>Failed</Status></Login>";
				}

			}

			return generateSuccessResponse(returnEncryptedPassword, loginId, password);

		} catch (ServletException e) {
			return "<Login><Status>Failed</Status><Error>" + e.getMessage() + "</Error></Login>";
		} catch (XPathExpressionException e) {
			return "<Login><Status>Failed</Status><Error>" + e.getMessage() + "</Error></Login>";
		} catch (ParserConfigurationException e) {
			return "<Login><Status>Failed</Status><Error>" + e.getMessage() + "</Error></Login>";
		} catch (IOException e) {
			return "<Login><Status>Failed</Status><Error>" + e.getMessage() + "</Error></Login>";
		} catch (SAXException e) {
			return "<Login><Status>Failed</Status><Error>" + e.getMessage() + "</Error></Login>";
		}

	}


	private String generateSuccessResponse(String returnEncryptedPassword, String loginId, String password) {

		String response = "<Login><Status>Success</Status>";

		response += "<LoginId>" + loginId + "</LoginId>";

		if (returnEncryptedPassword.equalsIgnoreCase("Yes")) {
			response += "<EncryptedPassword>" + Obfuscator.encrypt(password) + "</EncryptedPassword>";
		}

		response = response + "</Login>";
		return response;
	}
}
